package edu.towson.cosc.cosc455.fredasamoah.markdowncompiler;

import edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer;


public class MySyntaxAnalyzer implements SyntaxAnalyzer {
	
	
	//GO BACK AND DO DEFINE
	//GO BACK AND DO END DOCUMENT TO WORK ON CHECKING TOKEN FOR EMPTY
	
	private MyLexicalAnalyzer lexer = new MyLexicalAnalyzer();
	String allText[] = {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r",
			"s","t","u","v","w","x","y","z",".",",","+,","=","!","`","~","@","$","%","^","&","*",
			"-","_","(",")","<",">","?","/","'", " "};
	
	
	@Override
	public void document() throws CompilerException {
		// TODO Auto-generated method stub
		lexer.getNextToken();
		if(Compiler.token.equalsIgnoreCase("#Start Document")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			define();
			head();
			body();
			if(Compiler.token.equalsIgnoreCase("#End Document")){
				Compiler.vc.add(Compiler.token);
				lexer.getNextToken();
				if(Compiler.token.trim().length()!=0){
				//Check if empty
					String message = "An #End Document annotation was reached yet there is still contents left in your file " + Compiler.token;
					throw new CompilerException(message);
				}
			}
			else{
				String message = "An #End Document annotation was expected when a " + Compiler.token + " was found";
				throw new CompilerException(message);
			}
		}
		else{
			String message = "A #Start document annotation was expected when a " + Compiler.token + " was found";
			throw new CompilerException(message);
		}
		
	}

	public void body() throws CompilerException{
		
		for(int i = 0; i < allText.length; i++)
		{
			if(Compiler.token.equalsIgnoreCase(allText[i])){
				lexer.getNextToken();
				innertext();
				body();
			}
		}
		if(Compiler.token.equalsIgnoreCase("#Start paragraph")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			paragraph();
			body();
		}
		else if(Compiler.token.equalsIgnoreCase("#Start bold")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			bold();
			body();
		}
		else if(Compiler.token.equalsIgnoreCase("#Start italics")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			italics();
			body();
		}
		else if(Compiler.token.equalsIgnoreCase("#Start list")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			list();
			body();
		}
		else if(Compiler.token.equalsIgnoreCase("#Start video")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			video();
			body();
		}
		else if(Compiler.token.equalsIgnoreCase("#Start audio")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			audio();
			body();
		}
	}

	@Override
	public void head() throws CompilerException {
		// TODO Auto-generated method stub
		
		if(Compiler.token.equalsIgnoreCase("#Start head")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			title();
			if(Compiler.token.equalsIgnoreCase("#End head")){
				Compiler.vc.add(Compiler.token);
				lexer.getNextToken();
			}
			else{
				String message = "An #End head annotation was expected when a " + Compiler.token + " was found";
				throw new CompilerException(message);
			}
		}
	}

	@Override
	public void title() throws CompilerException {
		// TODO Auto-generated method stub
		
		if(Compiler.token.equalsIgnoreCase("#Start title")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			innertext();
			if(Compiler.token.equalsIgnoreCase("#End title")){
				Compiler.vc.add(Compiler.token);
				lexer.getNextToken();
			}
			else{
				String message = "A #End title annotation was expected when a " + Compiler.token + " was found";
				throw new CompilerException(message);
			}
		}
	}

	@Override
	public void paragraph() throws CompilerException {
		// TODO Auto-generated method stub
		
		define();
		inner_paragraph();
		if(Compiler.token.equalsIgnoreCase("#End paragraph")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
		}
		else{
			String message = "An #End paragraph annotation was expected when a " + Compiler.token + " was found";
			throw new CompilerException(message);
		}
	}

	public void inner_paragraph() throws CompilerException {
		// TODO Auto-generated method stub
		
		innertext();
		if(Compiler.token.equalsIgnoreCase("#Start bold")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			bold();
			inner_paragraph();
		}
		else if(Compiler.token.equalsIgnoreCase("#Start italics")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			italics();
			inner_paragraph();
		}
		else if(Compiler.token.equalsIgnoreCase("#Start list")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			list();
			inner_paragraph();
		}
		else if(Compiler.token.equalsIgnoreCase("#Start video")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			video();
			inner_paragraph();
		}
		else if(Compiler.token.equalsIgnoreCase("#Start audio")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			audio();
			inner_paragraph();
		}
	}

	@Override
	public void bold() throws CompilerException {
		// TODO Auto-generated method stub
		
		define();
		innertext();
		if(Compiler.token.equalsIgnoreCase("#End bold")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
		}
		else{
			String message = "A #Start bold annotation was expected when a " + Compiler.token + " was found";
			throw new CompilerException(message);
		}
	}

	@Override
	public void italics() throws CompilerException {
		// TODO Auto-generated method stub
		
		define();
		if(Compiler.token.equalsIgnoreCase("#End italics")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
		}
		else{
			String message = "An #End italics annaotation was expected when a " + Compiler.token + " was found";
			throw new CompilerException(message);
		}
	}

	@Override
	public void list() throws CompilerException {
		// TODO Auto-generated method stub
		
		while(Compiler.token.equalsIgnoreCase("#Start item")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			item();
		}
		if(Compiler.token.equalsIgnoreCase("#End list")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
		}
		else{
			String message = "An #End list annotation was expected when a " + Compiler.token + " was found";
			throw new CompilerException(message);
		}
	}

	public void innerlist() throws CompilerException{
		// TODO Auto-generated method stub
		
		if(Compiler.token.equalsIgnoreCase("#Start bold")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			bold();
			innerlist();
		}
		else if(Compiler.token.equalsIgnoreCase("#Start italics")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			italics();
			innerlist();
		}
		else if(Compiler.token.equalsIgnoreCase("#Start list")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			list();
			innerlist();
		}
		else if(!Compiler.token.contains("#")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
		}
	}

	@Override
	public void item() throws CompilerException {
		// TODO Auto-generated method stub
		
		define();
		innerlist();
		use();
		if(Compiler.token.equalsIgnoreCase("#End item")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
		}
		else{
			String message = "An #End item annotation was expected when a " + Compiler.token + " was found";
			throw new CompilerException(message);
		}
	}

	@Override
	public void audio() throws CompilerException {
		// TODO Auto-generated method stub
		
		text();
		if(Compiler.token.equalsIgnoreCase("#End audio")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
		}
		else{
			String message = "An #End audio annotation was expected when a " + Compiler.token + " was found";
			throw new CompilerException(message);
		}
		
	}

	@Override
	public void video() throws CompilerException {
		// TODO Auto-generated method stub
		
		text();
		if(Compiler.token.equalsIgnoreCase("#End video")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
		}
		else{
			String message = "An #End video annotation was expected when a " + Compiler.token + " was found";
			throw new CompilerException(message);
		}
	}

	@Override
	public void define() throws CompilerException {
		// TODO Auto-generated method stub
		
		if(Compiler.token.equalsIgnoreCase("#Start define")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			if(Compiler.token.equalsIgnoreCase("#Name")){
				Compiler.vc.add(Compiler.token);
				lexer.getNextToken();
				innertext();
				if(Compiler.token.equalsIgnoreCase("#Value")){
					Compiler.vc.add(Compiler.token);
					lexer.getNextToken();
					text();
					body();
					if(Compiler.token.equalsIgnoreCase("#End define")){
						Compiler.vc.add(Compiler.token);
						lexer.getNextToken();
						define();
					}
					else{
						String message = "A #End define annotation was expected when a " + Compiler.token + " was found";
						throw new CompilerException(message);
					}
				}
				else{
					String message = "A #Value annotation was expected when a " + Compiler.token + " was found";
					throw new CompilerException(message);
				}
			}
			else{
				String message = "A #Name annotation was expected when a " + Compiler.token + " was found";
				throw new CompilerException(message);
			}
		}
	}

	@Override
	public void use() throws CompilerException {
		// TODO Auto-generated method stub

		if(Compiler.token.equalsIgnoreCase("#Start use")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			text();
			if(Compiler.token.equalsIgnoreCase("#End use")){
				Compiler.vc.add(Compiler.token);
				lexer.getNextToken();
			}
			else{
				String message = "A #End use annotation was expected when a " + Compiler.token + " was found";
				throw new CompilerException(message);
			}
		}
	}

	public void text() throws CompilerException{
		// TODO Auto-generated method stub
		
		if(!Compiler.token.contains("#")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
		}
	}

	public void innertext() throws CompilerException{
		// TODO Auto-generated method stub
		
		
		
		if(Compiler.token.equalsIgnoreCase("#Start Use")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			use();
			innertext();
			if(Compiler.token.equalsIgnoreCase("#End use")){
				Compiler.vc.add(Compiler.token);
				lexer.getNextToken();
			}
			else{
				String message = "An #End use annotation was expected when a " + Compiler.token + " was found";
				throw new CompilerException(message);
			}
		}
		else if(Compiler.token.equalsIgnoreCase("#Newline")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			innertext();
		}
		else if(!Compiler.token.contains("#")){
			Compiler.vc.add(Compiler.token);
			lexer.getNextToken();
			innertext();
		}
	}

}
